#ifndef GRITC_SERVER_ACTOR_HPP
#define GRITC_SERVER_ACTOR_HPP

#include <vector>
#include <algorithm>

namespace gritc { namespace server {
	
	template<class Traits> struct actor
	{
		typedef typename Traits traits_type;
		typedef typename Traits::string_type string_type;
		typedef typename Traits::buff_type buff_type;
		typedef std::vector<buff_type*> buff_list;		

		string_type name_;
		string_type & name() { return name_; }

		buff_list buffs_;
		buff_list & buffs() { return buffs_; }

		actor(string_type const& n) : name_(n) {}
		virtual ~actor() {}

		template<class E> void act(E & e)
		{
			for(buff_list::iterator i = buffs_.begin(); i != buffs_.end(); ++i)
				(*i)->act(e);
		}

		virtual void respond(string_type const&) = 0;
	};

	struct tick_actor_
	{
		template<class Actor, class Tick, class Pointer>
		void operator ()(Actor & actor_, Tick & tick_, Pointer & pointer_) const
		{
			typedef Actor::buff_type Buff;
			typedef Actor::buff_list List;
			typedef Tick::time_type Time;

			List & buffs_ = actor_.buffs();
			List::iterator i = buffs_.begin();

			while(i != buffs_.end())
			{
				Buff & buff_ = **i;

				if(buff_.ttl != -1)
				{
					if(buff_.ttl < tick_.elapsed())
						buff_.ttl = 0;
					else
						buff_.ttl = buff_.ttl - tick_.elapsed();
				}

				// tick buff by passing the tick effect pointer
				buff_.act(pointer_);

				// if buff expires (ttl == 0) then remove it from our structure and clean up memory
				if(buff_.ttl == 0)
				{
					i = buffs_.erase(i);
					actor_.room().response() << "buffoff " << buff_.name() << " ";
					delete &buff_;
				}else
					++i;
			}
			
		}
	} const tick_actor;
}}

#endif